/**
 * 描述 : 对分页操作, 直接调用L.paging()为初始化所有分页, 从分页调用为功能操作
 * 参数 :
 *      type : 仅从分页对象中调用有效
 *          数字 : 跳转到指定页面, 1=第一页, -1=最后一页
 *          +/-n : 以当期页向后/前移动页数, '+1'=下一页, '-1'=上一页
 *          排序 : 排序指定字段, '字段名 ASC/DESC', 如: 'a ASC, b DESC'=正序a,倒序b
 *          条数 : 指定每页展示数量. '数字', 如: '4'=每页显示4条
 *          无值 : 返回共享参数
 *          对象 : 修改共享参数
 *      mode : type为对象时启用
 *          true  = 完全代替参数并刷新
 *          false = 完全代替参数不刷新
 *          null  = 单层替换参数并刷新(默认)
 * 返回 :
 *      
 * 注明 :
 *      已初始化列表结构(list) : [{
 *          'block' : 分页块对象
 *          'items' : 单行数据集 [{
 *              'itemObj' : 一个name='pagingItem'的对象
 *              'parent'  : itemObj对象的父节点
 *          }, ...],
 *          'sorts' : 分页排序状态 {
 *              字段名 : ASC / DESC, ...
 *          }
 *          'fbar'  : 功能条对象, null=没有
 *          'save'  : 保存状态字符串,存入cookie
 *              method + ":" + save + ":" + 默认params = L.json({
 *                  "params" : 最新params, 
 *                  "items"  : 总数据条目数
 *                  "size"   : 每页显示数
 *                  "page"   : 当期页数
 *                  "sort"   : 排序字段 "sorts" 对象
 *              })
 *          'lock'  : 等待锁,true=有请求, false=无请求
 *          'init'  : 是否需要初始化, true=需要, false=无需
 *      }, ...]
 * 作者 : Edgar.lee
 */
L.paging || (function () {
    var list = [], temp, frag = document.createElement('div');                                                          //已初始化列表, 临时存储, 碎片DIV
    var wrapMap = {                                                                                                     //转换标签
        "TR" : ["<table><tbody name='root'>", "</tbody></table>"],
        "TD" : ["<table><tbody><tr name='root'>", "</tr></tbody></table>"]
    }
    var getAttrObj = function (obj, name, val, attr, data) {                                                            //获取匹配属性的值
        var t = {'l' : obj.getElementsByTagName('*')}, result = [];
        typeof val === 'string' && (val = RegExp('^' + val + '$'));                                                     //字符串转正则

        for(var i = 0, iL = t.l.length; i < iL; ++i) {
            if( (t.v = t.l[i].getAttribute(name)) !== null && (val == null || val.test(t.v)) ) {                        //属性存在 && (不判断值 || 正则匹配)
                result.push(t.l[i]);                                                                                    //加入返回列表
                attr && (t.l[i][attr] = data);                                                                          //批量设置属性
            }
        }

        return result;
    }
    var eventFunc = function (event) {                                                                                  //分页事件总响应
        var target = event.target, space;
        do {
            if( target === this ) {
                return ;
            } else {
                space = list[L.search(list, this, 'block')[0]].space;                                                   //命名空间
                switch( target.getAttribute('name') ) {
                    case space + 'pagingSort' :                                                                         //排序
                        if( event.type !== 'click' || !(target = target.getAttribute('sort')) ) return ;                //点击 && 存在排序
                        break;
                    case space + 'pagingFirst':                                                                         //第一页
                        event.type === 'click' && (target = 1);
                        break;
                    case space + 'pagingPrev' :                                                                         //上一页
                        event.type === 'click' && (target = '-1');
                        break;
                    case space + 'pagingNext' :                                                                         //下一页
                        event.type === 'click' && (target = '+1');
                        break;
                    case space + 'pagingLast' :                                                                         //最后页
                        event.type === 'click' && (target = -1);
                        break;
                    case space + 'pagingJump' :                                                                         //跳转页
                        if( target.getAttribute('nth') !== null ) {                                                     //点击跳转
                            if( event.type === 'click' ) {
                                target = parseInt(target.getAttribute('value'), 10);
                                typeof target === 'number' || (target = 1);
                            }
                            break;
                        }
                    case space + 'pagingSize' :                                                                         //展示数
                        if( event.type === 'mouseover' ) {                                                              //全选
                            target.focus();
                            target.select();
                        } else if( event.type === 'keyup' && event.event.keyCode === 13 ) {                             //回车
                            if( target.getAttribute('name') === space + 'pagingSize' ) {
                                target = target.value;
                            } else if( !isNaN(parseInt(target.value, 10)) ) {
                                target = parseInt(target.value, 10);
                            }
                        }
                        break;
                }

                if( typeof target !== 'object' ) {
                    L.paging.call(this, target);
                    return false;
                }
            }
        } while ( target = target.parent );
    }
    var layoutFunc = function (data) {
        var tObj = {                                                                                                    //当前对象
            'b' : list[this].block, 'i' : list[this].items, 's' : list[this].sorts, 
            'd' : L.json(data), 'n' : list[this].space, 'r' : RegExp('(`*){`' +list[this].space+ '(.+?)`}', 'g')
        };

        if( tObj.d ) {                                                                                                  //json有效
            data = L.json(data);                                                                                        //操作数据
            tObj.b.data = tObj.d.data;                                                                                  //引用数据

            tObj.b.setAttribute('method', data.method);                                                                 //设置回调
            tObj.b.setAttribute('items', data.items);                                                                   //设置总长
            tObj.b.setAttribute('page', data.page = parseInt(data.page, 10));                                           //当前页面
            tObj.b.setAttribute('params', data.params = L.json(data.params));                                           //共享参数
            tObj.b.setAttribute('size', data.size);                                                                     //页面总数

            tObj.removes = getAttrObj(tObj.b, 'name', tObj.n + 'pagingItem');                                           //准备移除单行
            tObj.maxPage = data.items > -1 ? Math.ceil(data.items / data.size) : '∞';                                   //最大页面
            tObj.w = data.page + '/' + tObj.maxPage;                                                                    //当前位置
            getAttrObj(tObj.b, 'name', tObj.n + 'pagingPage', 'innerHTML', tObj.w);                                     //显示位置
            getAttrObj(tObj.b, 'name', tObj.n + 'pagingSize', 'value', data.size);                                      //显示尺寸
            getAttrObj(tObj.b, 'name', tObj.n + 'pagingJump', 'value',                                                  //显示跳转
                data.page + 1 > tObj.maxPage ? 1 : data.page + 1
            );

            tObj.w = getAttrObj(tObj.b, 'name', tObj.n + 'pagingWait');                                                 //隐藏等待
            for(var i in tObj.w) tObj.w[i].style.display = 'none';

            tObj.w = getAttrObj(tObj.b, 'name', tObj.n + 'pagingLast');                                                 //隐藏显示最后一页
            for(var i in tObj.w) tObj.w[i].style.display = data.items > -1 ? '' : 'none';

            tObj.w = getAttrObj(tObj.b, 'name', tObj.n + 'pagingEmpty');                                                //隐藏空无

            if( L.count(data.data) ) {
                for(var i in tObj.w) tObj.w[i].style.display = 'none';                                                  //隐藏无数据

                for(var i in data.data) {                                                                               //遍历数据
                    for(var j in tObj.w = data.data[i]) j.substr(0, 1) === '_' || (tObj.w[j] = L.entity(tObj.w[j]));    //不以"_"开头的属性进行html编码
                    tObj.t = tObj.i[i % tObj.i.length];                                                                 //使用的数据条
                    tObj.t.itemObj.outerHTML || (tObj.t.itemObj.outerHTML = document.createElement('div').appendChild(tObj.t.itemObj).parentNode.innerHTML);
                    tObj.w = tObj.t.itemObj.outerHTML.replace(tObj.r, function (all, bac, key) {                        //反引号, 关键词
                        if( bac.length % 2 ) {                                                                          //单数"`"
                            return all.substr(Math.ceil(bac.length / 2)) 
                        } else {
                            return bac.substr(bac.length / 2) + (data.data[i][key] == null ? '' : data.data[i][key]);
                        }
                    });

                    if( tObj.m = wrapMap[tObj.t.itemObj.tagName] ) {                                                    //tr td 转换
                        frag.innerHTML = 't' + tObj.m[0] + tObj.w + tObj.m[1];
                        tObj.w = getAttrObj(frag, 'name', 'root')[0].firstChild
                    } else {                                                                                            //其它转换
                        frag.innerHTML = 't' + tObj.w;
                        tObj.w = frag.childNodes[1];
                    }
                    tObj.t.parent.appendChild(tObj.w);                                                                  //插入父类最后位置
                }
            } else {                                                                                                    //无数据
                for(var i in tObj.w) tObj.w[i].style.display = '';                                                      //显示无数据
            }

            for(var i in tObj.removes) tObj.removes[i].parentNode.removeChild(tObj.removes[i]);                         //移除单行

            tObj.w = getAttrObj(tObj.b, 'name', tObj.n + 'pagingSort');                                                 //修改排序图标
            for(var i in tObj.w) {
                for(var j in tObj.t = (tObj.w[i].getAttribute('sort') || '').split(/\s+/)) {
                    if( typeof tObj.s[tObj.t[j]] === 'string' ) {                                                       //字符串
                        tObj.w[i].className = tObj.w[i].className.replace(/\b\s*of-paging_sort_(?:asc|desc)\b\s*/g, ' ');
                        tObj.w[i].className += ' of-paging_sort_' + tObj.s[tObj.t[j]].toLowerCase();
                    }
                }
            }

            if( list[this].save ) {                                                                                     //保存状态
                L.cookie(list[this].save + L.param({
                    '' : L.json({
                        'params' : data.params,
                        'items'  : data.items,
                        'size'   : data.size,
                        'page'   : data.page,
                        'sort'   : tObj.s
                    })
                }).substr(1));
            }

            tObj.w = getAttrObj(tObj.b, 'name', tObj.n + 'pagingJump');                                                 //修改跳转按钮
            for(var i in tObj.w) {
                if( (tObj.t = tObj.w[i]).getAttribute('nth') !== null ) {                                               //跳转按钮
                    tObj.t.style.display = 'none';                                                                      //隐藏元素
                    tObj.t = tObj.t.getAttribute('nth').replace(/(`*){`(.+?)`}/g, function (all, bac, key) {
                        if( bac.length % 2 === 0 ) {                                                                    //有效跳转次数
                            key = L.json(key.replace(/\bm\b/g, tObj.maxPage)                                            //L.json 代替 eval
                                .replace(/\bp\b/g, tObj.b.getAttribute('page'))                                         //计算最后结果
                            );

                            if( 
                                typeof key === 'number' && key > 0 &&                                                   //数值 && > 0
                                (tObj.maxPage === '∞' || key <= tObj.maxPage)                                           //小于等于最大页
                            ) {                                                                                         //key值有效
                                tObj.t.style.display = '';                                                              //显示元素
                                tObj.t.setAttribute('value', key);                                                      //赋值计算值
                                return all.substr(0, bac.length / 2) + key;
                            }
                        }
                    });

                    tObj.w[i].innerHTML = tObj.t;                                                                       //展示可见值
                }
            }

            list[this].lock = false;                                                                                    //解锁

            tObj.w = L.data('paging.after');                                                                            //触发翻页后事件
            for(var i in tObj.w) if( tObj.w[i].call(tObj.b, 'after') === false ) break ;

            L.paging(tObj.b);

            if( list[this].init ) {                                                                                     //没有初始化
                list[this].init = false;                                                                                //标记初始化
                tObj.w = L.data('paging.init');                                                                         //触发初始化事件
                for(var i in tObj.w) if( tObj.w[i].call(tObj.b, 'init') === false ) return ;
            }
        }
    }
    var fbarFunc = function (event) {
        if( this === document || event.type === 'resize' ) {                                                            //fbar调整
            for(var i in list) {
                if(
                    list[i].fbar && (                                                                                   //功能条存在
                        list[i].fbar.currentStyle ? list[i].fbar.currentStyle : getComputedStyle(list[i].fbar, false)
                    ).display !== 'none'
                ) {
                    list[i].fbar.style.width = 
                        (100 - Math.ceil(L.val(list[i].fbar.parentNode.getElementsByTagName('div'), '[-1]').offsetWidth * 100 / list[i].fbar.parentNode.clientWidth)) + '%';
                    if( list[i].fbar.getElementsByTagName('div')[0].offsetWidth < list[i].fbar.offsetWidth - 50 ) {
                        list[i].fbar.style.width = '';
                        L.val(list[i].fbar.getElementsByTagName('label'), '[-1]').style.display = 'none';
                    } else {
                        L.val(list[i].fbar.getElementsByTagName('label'), '[-1]').style.display = '';
                    }
                }
            }
        } else {                                                                                                        //fbar展开
            this.style.width = '';
        }
        return false;
    }

    frag.innerHTML = 't<link type="text/css" rel="stylesheet" href="paging/main.css">';     //创建样式
    document.getElementsByTagName('head')[0].appendChild(frag.childNodes[1]);                                           //添加样式
    L.data('paging.init[]', L.data('paging.before[]', L.data('paging.after[]', function(type){                          //回调脚本
        return (new Function('var type = "' + type + '";\n' + this.getAttribute('event'))).call(this);
    })));

    L.paging = function (type, mode) {                                                                                  //分页方法
        if( this.tagName ) {                                                                                            //分页调用
            switch( typeof type ) {
                case 'undefined':                                                                                       //读取参数
                case 'object'   :                                                                                       //修改参数
                    L.type(temp = L.json(this.getAttribute('params'))) || (temp = {});

                    if( type === undefined ) {                                                                          //读取参数
                        return temp;
                    } else {
                        mode == null ? L.each(temp, type) : (temp = type);                                              //单层替换 || 完全替换
                        this.setAttribute('params', L.json(temp));                                                      //修改参数
                        this.setAttribute('items', '');                                                                 //重新计算总长

                        if( mode === false ) {                                                                          //不刷新
                            return ;
                        } else {                                                                                        //刷新分页
                            type = '+0';
                        }
                    }
                case 'string'   :
                    if( /^\d+$/.test(type) ) {                                                                          //设置展示数
                        this.setAttribute('size', type);
                        type = '+0';
                    } else if( !/^(?:\+|-)\d+$/.test(type) ) {                                                          //排序字段
                        temp = {'l' : type.split(/\s*,\s*/), 's' : {}, 'k' : L.search(list, this, 'block')[0]};
                        for(var i in temp.l) {
                            temp.t = temp.l[i].split(' ');
                            temp.t[1] || (temp.t[1] = list[temp.k].sorts[temp.t[0]] === 'DESC' ? 'ASC' : 'DESC');       //自动切换
                            temp.s[temp.t[0]] = temp.t[1] === 'DESC' ? 'DESC' : 'ASC';                                  //指定切换
                        }
                        list[temp.k].sorts = L.each(temp.s, false, list[temp.k].sorts);                                 //单层补充
                        type = '+0';
                    }
                    temp = {'m' : parseInt(type, 10), 'p' : parseInt(this.getAttribute('page'), 10)};                   //{'m' : 偏移位置, 'p' : 当期页面}
                    isNaN(temp.m) && (temp.m = 0);
                    isNaN(temp.p) && (temp.p = 1);
                    (type = temp.p + temp.m) < 1 && (type = 1);                                                         //真实位置
                case 'number'   :
                    temp = {'i' : parseInt(this.getAttribute('items'), 10), 's' : parseInt(this.getAttribute('size'), 10), 't' : []}
                    if( temp.i > -1 && temp.s > 0 ) {
                        temp.m = Math.ceil(temp.i / temp.s);                                                            //最大页数
                        type > 0 ? type > temp.m && (type = temp.m) : (type += temp.m + 1);                             //正数溢出纠正
                    }
                    type < 1 && (type = 1);                                                                             //负数溢出纠正

                    if( list[temp.k = L.search(list, this, 'block')[0]].lock === false ) {                              //可以发送请求
                        list[temp.k].lock = true;
                        temp.w = getAttrObj(list[temp.k].block, 'name', list[temp.k].space + 'pagingWait');             //显示等待
                        for(var i in temp.w) temp.w[i].style.display = '';

                        temp.w = L.data('paging.before');                                                               //触发翻页前事件
                        for(var i in temp.w) if( temp.w[i].call(this, 'before') === false ) return ;

                        temp.m = this.getAttribute('method');                                                           //使用的方法
                        temp.p = this.getAttribute('params');                                                           //共享参数
                        if( 
                            list[temp.k].init &&                                                                        //没初始化
                            list[temp.k].save &&                                                                        //状态保存
                            (temp.c = L.cookie(list[temp.k].save + '`t'))                                               //成功读取保存信息
                        ) {
                            temp.c = L.json(temp.c);
                            temp.i = temp.c.items;                                                                      //总条数
                            temp.s = temp.c.size;                                                                       //显示条数
                            temp.p = temp.c.params;                                                                     //共享参数
                            list[temp.k].sorts = temp.c.sort;                                                           //排序状态
                            type = temp.c.page;                                                                         //当前页数
                        }

                        temp.d = list[temp.k].sorts;                                                                    //分页数据引用
                        for(var i in temp.d) temp.t.push(i + ' ' + temp.d[i]);                                          //整理排序列表

                        L.ajax({                                                                                        //发起请求
                            'url'     : 'common.php',
                            'context' : temp.k,
                            'data'    : {
                                'get'  : 'c=com_common&a=paging'+ms,
                                'post' : {
                                    'method' : temp.m,
                                    'items'  : temp.i,
                                    'size'   : temp.s,
                                    'page'   : type,
                                    'sort'   : temp.t.join(', '),
                                    'params' : temp.p
                                }
                            },
                            'success' : layoutFunc
                        });
                    }
            }
        } else {                                                                                                        //系统调用
            var blocks = getAttrObj(type || (type = document), 'name', /^(\w+:)?pagingBlock$/), index, space;
            for(var i in blocks) {
                temp = blocks[i];
                while( (temp = temp.parentNode) && temp !== type ) {}
                if( !temp ) continue;

                if( !L.search(list, blocks[i], 'block') ) {                                                             //开始初始化
                    space= (space = blocks[i].getAttribute('name')).indexOf(':') > -1 ?                                 //命名空间
                        space.split(':')[0] + ':' : '';
                    temp = getAttrObj(blocks[i], 'name', space + 'pagingItem');                                         //读取单行对象

                    if( temp.length ) {                                                                                 //有效分页
                        index = {'block' : blocks[i], 'items' : [], 'sorts' : {}, 'lock' : false, 'init' : true, 'space' : space};

                        for(var j in temp) {
                            index.items.push({'itemObj' : temp[j], 'parent' : temp[j].parentNode});                     //保存节点
                            temp[j].parentNode.removeChild(temp[j]);                                                    //移除节点
                            temp[j].style.display = '';                                                                 //删除隐藏属性
                        }

                        if( index.save = blocks[i].getAttribute('save') || '' ) {                                       //保存状态
                            temp = blocks[i].getAttribute('method') + ':' + index.save + ':' + (blocks[i].getAttribute('params') || '');
                            index.save = { 'of_base_com_common' : { 'pagingSave' : {} } };
                            index.save.of_base_com_common.pagingSave[temp] = '';
                            index.save = L.param(index.save);
                        }

                        if( index.fbar = getAttrObj(blocks[i], 'name', space + 'pagingFbar')[0] ) {                     //读取功能条
                            L.event(index.fbar, 'mouseover', fbarFunc);                                                 //移动事件
                            index.fbar.style.width = '50%';
                        }

                        list.push(index);                                                                               //加入列表

                        L.event(blocks[i], 'click', eventFunc);                                                         //点击事件
                        L.event(blocks[i], 'keyup', eventFunc);                                                         //按键事件
                        L.event(blocks[i], 'mouseover', eventFunc);                                                     //移动事件
                        blocks[i].paging = L.paging;                                                                    //内置方法

                        L.paging.call(blocks[i], '+0');                                                                 //刷新页面
                    }
                }
            }
        }
    }

    L.event(function () {                                                                                               //完成事件
        L.event(document, 'mouseover', fbarFunc);
        L.event(window, 'resize', fbarFunc);
        L.paging();
    });
})();